Source for file SC_GraphLine.php

Documentation is available at SC_GraphLine.php

  1. <?php
  2. /*
  3.  * This file is part of EC-CUBE
  4.  *
  5.  * Copyright(c) 2000-2007 LOCKON CO.,LTD. All Rights Reserved.
  6.  *
  7.  * http://www.lockon.co.jp/
  8.  *
  9.  * This program is free software; you can redistribute it and/or
  10.  * modify it under the terms of the GNU General Public License
  11.  * as published by the Free Software Foundation; either version 2
  12.  * of the License, or (at your option) any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  22.  */
  23. $SC_GRAPHLINE_DIR = realpath(dirname( __FILE__));
  24. require_once($SC_GRAPHLINE_DIR . "/SC_GraphBase.php");
  25.  
  26. // 折れ線グラフ生成クラス
  27. class SC_GraphLine extends SC_GraphBase{
  28.     var $area_width;
  29.     var $area_height;
  30.     var $ygrid_on;
  31.     var $graph_max;     // グラフのエリア最大値(Y軸頂点の値)
  32.     var $arrXLabel;
  33.     var $XLabelAngle;   // X軸ラベル角度
  34.     var $XTitle;        // X軸タイトル
  35.     var $YTitle;        // Y軸タイトル
  36.     var $arrDataList;   // グラフデータを格納
  37.     var $arrPointList;  // 折れ線座標を格納
  38.     var $line_max;      // 複数の描画の場合に加算していく
  39.  
  40.     var $x_margin;
  41.     var $y_margin;
  42.  
  43.     // コンストラクタ
  44.     function SC_GraphLine(
  45.         $bgw = BG_WIDTH, $bgh = BG_HEIGHT, $left = LINE_LEFT, $top = LINE_TOP,
  46.         $area_width = LINE_AREA_WIDTH, $area_height = LINE_AREA_HEIGHT) {
  47.         parent::SC_GraphBase($bgw, $bgh, $left, $top);
  48.         $this->area_width = $area_width;
  49.         $this->area_height = $area_height;
  50.         $this->ygrid_on = true;
  51.         $this->line_max = 0;
  52.         $this->graph_max = 0;
  53.         $this->XLabelAngle = 0;
  54.         $this->x_margin = 0;
  55.         $this->y_margin = 0;
  56.     }
  57.  
  58.     // X軸ラベルの角度セット
  59.     function setXLabelAngle($Angle) {
  60.         $this->XLabelAngle = $Angle;
  61.     }
  62.  
  63.     // Y軸タイトル
  64.     function drawYTitle() {
  65.         // Y軸にタイトルを入れる
  66.         if($this->YTitle != "") {
  67.             $text_width = $this->getTextWidth($this->YTitle, FONT_SIZE);
  68.             $x_pos = $this->left - ($text_width / 2);
  69.             $y_pos = $this->top - FONT_SIZE - LINE_YTITLE_PAD;
  70.             $this->setText(FONT_SIZE, $x_pos, $y_pos, $this->YTitle);
  71.         }
  72.     }
  73.  
  74.     // X軸タイトル
  75.     function drawXTitle() {
  76.         // Y軸にタイトルを入れる
  77.         if($this->XTitle != "") {
  78.             $text_width = $this->getTextWidth($this->XTitle, FONT_SIZE);
  79.             $x_pos = $this->left + $this->area_width - ($text_width / 2) + 30;
  80.             $y_pos = $this->top + $this->area_height + LINE_XTITLE_PAD;
  81.             $this->setText(FONT_SIZE, $x_pos, $y_pos, $this->XTitle);
  82.         }
  83.     }
  84.  
  85.     // Y軸の描画
  86.     function drawYLine() {
  87.         imageline($this->image, $this->left, $this->top, $this->left, $this->top + $this->area_height, $this->flame_color);
  88.         // 目盛り幅を求める(中間点は自動)
  89.         $size = $this->area_height / (LINE_Y_SCALE * 2);
  90.         // 上から目盛りを入れていく
  91.         $pos = 0;
  92.         for($i = 0; $i < (LINE_Y_SCALE * 2); $i++) {
  93.             // 目盛り幅
  94.             if(($i % 2) == 0) {
  95.                 $sw = LINE_SCALE_SIZE;
  96.                 if($this->ygrid_on) {
  97.                     imageline($this->image, $this->left, $this->top + $pos, $this->left + $this->area_width, $this->top + $pos, $this->grid_color);
  98.                 }
  99.             } else {
  100.                 $sw = LINE_SCALE_SIZE / 2;
  101.             }
  102.             imageline($this->image, $this->left, $this->top + $pos, $this->left + $sw, $this->top + $pos, $this->flame_color);
  103.             $pos += $size;
  104.         }
  105.         // Y軸に目盛り値を入れる
  106.         $this->setYScale();
  107.         $this->drawYTitle();
  108.     }
  109.  
  110.     // X軸の描画
  111.     function drawXLine($bar = false) {
  112.         imageline($this->image, $this->left, $this->top + $this->area_height, $this->left + $this->area_width, $this->top + $this->area_height, $this->flame_color);
  113.         $arrPointList = $this->arrPointList[0];
  114.         $count = count($arrPointList);
  115.  
  116.         // 棒グラフの場合は半目盛りずらす
  117.         if($bar) {
  118.             $half_scale = intval($this->area_width / ($count + 1) / 2);
  119.         } else {
  120.             $half_scale = 0;
  121.         }
  122.  
  123.         // ラベルの表示インターバルを算出
  124.         $interval = ceil($count / LINE_XLABEL_MAX); // 切り上げ
  125.         for($i = 0; $i < $count; $i++) {
  126.             // X軸に目盛りを入れる
  127.             $x = $arrPointList[$i][0];
  128.             $pos = $this->top + $this->area_height;
  129.             imageline($this->image, $x - $half_scale, $pos, $x - $half_scale, $pos - LINE_SCALE_SIZE,  $this->flame_color);
  130.             // ラベルを入れる
  131.             if(($i % $interval) == 0) {
  132.                 $text_width = $this->getTextWidth($this->arrXLabel[$i], FONT_SIZE);
  133.                 $x_pos = $x;
  134.  
  135.                 if ($bar) {
  136.                     $bar_margin = -15;
  137.                 } else {
  138.                     $bar_margin = 0;
  139.                 }
  140.  
  141.                 $this->setText(FONT_SIZE, $x_pos + $this->x_margin + $bar_margin, $pos + FONT_SIZE + $this->y_margin, $this->arrXLabel[$i], NULL, $this->XLabelAngle);
  142.             }
  143.         }
  144.  
  145.         // 棒グラフの場合は最後の目盛りを一つ追加する
  146.         if($bar) {
  147.             imageline($this->image, $x + $half_scale, $pos, $x + $half_scale, $pos - LINE_SCALE_SIZE,  $this->flame_color);
  148.         }
  149.  
  150.         $this->drawXTitle();
  151.     }
  152.  
  153.     // グリッド表示
  154.     function setYGridOn($ygrid_on) {
  155.         $this->ygrid_on = $ygrid_on;
  156.     }
  157.  
  158.     // ポイントの描画
  159.     function setMark($line_no, $left, $top, $size = LINE_MARK_SIZE) {
  160.         // 偶数に変換しておく
  161.         $size += $size % 2;
  162.         $array = array(
  163.             $left, $top - ($size / 2),
  164.             $left + ($size / 2), $top,
  165.             $left, $top + ($size / 2),
  166.             $left - ($size / 2), $top,
  167.         );
  168.         imagefilledpolygon($this->image, $array, 4, $this->arrColor[$line_no]);
  169.         imagepolygon($this->image, $array, 4, $this->flame_color);
  170.         imagesetpixel ($this->image, $left, $top + ($size / 2), $this->flame_color);
  171.     }
  172.  
  173.     // Y軸目盛りに値を入れる
  174.     function setYScale() {
  175.         // 1目盛りの値
  176.         $number = intval($this->graph_max / LINE_Y_SCALE);
  177.         // 目盛り幅を求める
  178.         $size = $this->area_height / LINE_Y_SCALE;
  179.         $pos = 0;
  180.         for($i = 0; $i <= LINE_Y_SCALE; $i++) {
  181.             $snumber = $number * (LINE_Y_SCALE - $i);
  182.             $disp_number = number_format($snumber);
  183.             $num_width = $this->getTextWidth($disp_number, FONT_SIZE);
  184.             $this->setText(FONT_SIZE, $this->left - $num_width - 2, $this->top + $pos - (FONT_SIZE / 2), $disp_number);
  185.             $pos += $size;
  186.         }
  187.     }
  188.  
  189.     //
  190.     function setMax($arrData) {
  191.         // データの最大値を取得する。
  192.         $data_max = max($arrData);
  193.         // 10の何倍かを取得
  194.         $figure = strlen($data_max) - 1;
  195.         // 次の桁を計算する
  196.         $tenval = pow(10, $figure);
  197.         // グラフ上での最大値を求める
  198.         $this->graph_max = $tenval * (intval($data_max / $tenval) + 1);
  199.         // 最大値が10未満の場合の対応
  200.         if($this->graph_max < 10) {
  201.             $this->graph_max = 10;
  202.         }
  203.     }
  204.  
  205.     // グラフの描画
  206.     function drawGraph() {
  207.         // グラフ背景を描画
  208.         $this->drawYLine();
  209.         $this->drawXLine();
  210.  
  211.         // 折れ線グラフ描画
  212.         for($i = 0; $i < $this->line_max; $i++) {
  213.             $this->drawLine($i);
  214.         }
  215.  
  216.         // マークを描画
  217.         for($i = 0; $i < $this->line_max; $i++) {
  218.             $this->drawMark($i);
  219.         }
  220.  
  221.         // ラベルを描画
  222.         for($i = 0; $i < $this->line_max; $i++) {
  223.             $this->drawLabel($i);
  224.         }
  225.  
  226.         // 凡例の描画
  227.         $this->drawLegend();
  228.     }
  229.  
  230.     // ラインを描画する
  231.     function drawLine($line_no) {
  232.         $arrPointList = $this->arrPointList[$line_no];
  233.  
  234.         $count = count($arrPointList);
  235.         for($i = 0; $i < $count; $i++) {
  236.             $x = $arrPointList[$i][0];
  237.             $y = $arrPointList[$i][1];
  238.             if(isset($arrPointList[$i + 1])) {
  239.                 $next_x = $arrPointList[$i + 1][0];
  240.                 $next_y = $arrPointList[$i + 1][1];
  241.                 imageline($this->image, $x, $y, $next_x, $next_y, $this->arrColor[$line_no]);
  242.             }
  243.         }
  244.     }
  245.  
  246.     // マークを描画する
  247.     function drawMark($line_no) {
  248.         $arrPointList = $this->arrPointList[$line_no];
  249.         $count = count($arrPointList);
  250.         for($i = 0; $i < $count; $i++) {
  251.             $x = $arrPointList[$i][0];
  252.             $y = $arrPointList[$i][1];
  253.             $this->setMark($line_no, $x, $y);
  254.         }
  255.     }
  256.  
  257.     // ラベルを描画する
  258.     function drawLabel($line_no) {
  259.         $arrData = $this->arrDataList[$line_no];
  260.         $arrPointList = $this->arrPointList[$line_no];
  261.         $count = count($arrPointList);
  262.         for($i = 0; $i < $count; $i++) {
  263.             $x = $arrPointList[$i][0];
  264.             $y = $arrPointList[$i][1];
  265.             $text_width = $this->getTextWidth(number_format($arrData[$i]), FONT_SIZE);
  266.             $y_pos = $y - FONT_SIZE - 5;
  267.             $x_pos = $x - $text_width / 2;
  268.             $this->setText(FONT_SIZE, $x_pos, $y_pos, number_format($arrData[$i]));
  269.         }
  270.     }
  271.  
  272.     // データをセットする
  273.     function setData($arrData) {
  274.         $this->arrDataList[$this->line_max] = array_values((array)$arrData);
  275.         $this->setMax($this->arrDataList[$this->line_max]);
  276.         // 値の描画変換率
  277.         $rate = $this->area_height / $this->graph_max;
  278.         // 描画率を計算
  279.         $count = count($this->arrDataList[$this->line_max]);
  280.         $scale_width = $this->area_width / ($count + 1);
  281.         $this->arrPointList[$this->line_max] = array();
  282.         for($i = 0; $i < $count; $i++) {
  283.             // X座標を求める
  284.             $x = intval($this->left + ($scale_width * ($i + 1)));
  285.             // Y座標を求める
  286.             $y = intval($this->top + $this->area_height - ($this->arrDataList[$this->line_max][$i] * $rate));
  287.             // XY座標を保存する
  288.             $this->arrPointList[$this->line_max][] = array($x, $y);
  289.         }
  290.         $this->line_max++;
  291.     }
  292.  
  293.     // X軸ラベルをセットする
  294.     function setXLabel($arrXLabel) {
  295.         $this->arrXLabel = array_values((array)$arrXLabel);
  296.     }
  297.  
  298.     // X軸タイトルをセットする
  299.     function setXTitle($title) {
  300.         $this->XTitle = $title;
  301.     }
  302.  
  303.     // Y軸タイトルをセットする
  304.     function setYTitle($title) {
  305.         $this->YTitle = $title;
  306.     }
  307. }
  308. ?>

Documentation generated on Tue, 28 Apr 2009 18:13:22 +0900 by phpDocumentor 1.4.2